// Gemini API 服务层 - Chat兼容格式
const API_CONFIG = require('../config/api.config.js')
const { SCENARIO_TEMPLATES, TONE_STYLES, REPLY_LENGTHS } = require('../config/scenarios.config.js')

class GeminiService {
  constructor() {
    this.apiKey = API_CONFIG.API_KEY
    this.baseUrl = API_CONFIG.API_BASE_URL
    this.chatEndpoint = API_CONFIG.CHAT_ENDPOINT
    this.defaultModel = API_CONFIG.DEFAULT_MODEL
  }

  /**
   * 生成聊天回复建议
   * @param {Object} params - 生成参数
   * @param {string} params.message - 收到的消息内容
   * @param {string} params.scenarioId - 场景ID
   * @param {string} params.toneStyleId - 语气风格ID（可选）
   * @param {string} params.replyLengthId - 回复长度ID（可选）
   * @returns {Promise<Array>} 回复建议数组
   */
  async generateReplies(params) {
    const { message, scenarioId = 'general', toneStyleId = null, replyLengthId = 'medium' } = params

    // 验证输入
    if (!message || message.trim() === '') {
      throw new Error('消息内容不能为空')
    }

    if (message.length > API_CONFIG.MAX_INPUT_LENGTH) {
      throw new Error(`消息内容不能超过 ${API_CONFIG.MAX_INPUT_LENGTH} 字`)
    }

    // 构建 Chat 格式消息
    const messages = this._buildMessages(message, scenarioId, toneStyleId, replyLengthId)

    // 调用 Chat API
    try {
      const responses = await this._callChatAPI(messages, scenarioId)
      return responses
    } catch (error) {
      console.error('API 调用失败:', error)
      throw error
    }
  }

  /**
   * 构建 Chat 格式的消息
   * @private
   */
  _buildMessages(message, scenarioId, toneStyleId, replyLengthId) {
    const scenario = SCENARIO_TEMPLATES[scenarioId] || SCENARIO_TEMPLATES.general
    const replyLength = REPLY_LENGTHS[replyLengthId] || REPLY_LENGTHS.medium

    let systemPrompt = scenario.systemPrompt

    // 添加语气风格修饰
    if (toneStyleId && TONE_STYLES[toneStyleId]) {
      systemPrompt += `\n${TONE_STYLES[toneStyleId].modifier}`
    }

    // 添加长度要求
    systemPrompt += `\n回复长度控制在 ${replyLength.maxLength} 字以内。`

    // 构建用户消息
    const userMessage = `请根据以下收到的消息，生成 3 个不同风格的回复建议：

收到的消息：${message}

要求：
1. 生成 3 个不同的回复选项
2. 每个回复要有不同的表达方式和情感倾向
3. 每个回复要自然、得体、符合场景
4. 为每个回复标注一个适合的语气风格（从以下选择：温柔、幽默、正式、随意、热情、沉稳）
5. 给每个回复打一个情商得分（1-10分，10分最高）

请按以下 JSON 格式返回（只返回 JSON，不要有其他内容）：
{
  "replies": [
    {
      "content": "回复内容",
      "toneStyle": "语气风格",
      "eqScore": 8
    }
  ]
}`

    // 返回 chat 格式的消息数组
    return [
      {
        role: 'system',
        content: systemPrompt
      },
      {
        role: 'user',
        content: userMessage
      }
    ]
  }

  /**
   * 调用 Chat API（兼容 OpenAI 格式）
   * @private
   */
  async _callChatAPI(messages, scenarioId) {
    const scenario = SCENARIO_TEMPLATES[scenarioId] || SCENARIO_TEMPLATES.general

    const requestBody = {
      model: this.defaultModel,
      messages: messages,
      max_tokens: API_CONFIG.DEFAULT_MAX_TOKENS,
      temperature: scenario.temperature || API_CONFIG.DEFAULT_TEMPERATURE,
      top_p: API_CONFIG.DEFAULT_TOP_P,
      n: API_CONFIG.DEFAULT_N,
      stream: API_CONFIG.ENABLE_STREAM
    }

    // 使用微信小程序的 request API
    return new Promise((resolve, reject) => {
      wx.request({
        url: `${this.baseUrl}${this.chatEndpoint}`,
        method: 'POST',
        header: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'Authorization': `Bearer ${this.apiKey}`
        },
        data: requestBody,
        timeout: API_CONFIG.REQUEST_TIMEOUT,
        success: (res) => {
          console.log('API响应:', res)

          if (res.statusCode === 200 && res.data) {
            try {
              // Chat API 响应格式
              if (res.data.choices && res.data.choices.length > 0) {
                const content = res.data.choices[0].message?.content || ''

                // 尝试解析 JSON
                const jsonMatch = content.match(/\{[\s\S]*\}/)
                if (jsonMatch) {
                  const parsedResponse = JSON.parse(jsonMatch[0])

                  if (parsedResponse.replies && Array.isArray(parsedResponse.replies)) {
                    // 按情商得分排序
                    const sortedReplies = parsedResponse.replies.sort((a, b) => b.eqScore - a.eqScore)
                    resolve(sortedReplies)
                  } else {
                    reject(new Error('API 返回格式错误'))
                  }
                } else {
                  // 如果没有找到 JSON，尝试将纯文本分割成多个回复
                  const fallbackReplies = this._parseFallbackResponse(content)
                  resolve(fallbackReplies)
                }
              } else {
                reject(new Error('API 返回数据格式错误'))
              }
            } catch (error) {
              console.error('解析响应失败:', error)
              reject(new Error('解析 API 响应失败: ' + error.message))
            }
          } else {
            const errorMsg = res.data?.error?.message || `API 请求失败: ${res.statusCode}`
            reject(new Error(errorMsg))
          }
        },
        fail: (error) => {
          console.error('API 请求失败:', error)

          // 提供更详细的错误信息
          let errorMessage = '网络请求失败'

          if (error.errMsg) {
            if (error.errMsg.includes('request:fail')) {
              if (error.errMsg.includes('timeout')) {
                errorMessage = '请求超时，请稍后重试'
              } else if (error.errMsg.includes('url not in domain list')) {
                errorMessage = '域名未配置，请在开发者工具中关闭域名校验（详情->本地设置）'
              } else if (error.errMsg.includes('fail ssl')) {
                errorMessage = 'SSL证书错误，请检查服务器配置'
              } else {
                errorMessage = `网络请求失败: ${error.errMsg}`
              }
            }
          }

          reject(new Error(errorMessage))
        }
      })
    })
  }

  /**
   * 解析备用响应格式（当 JSON 解析失败时）
   * @private
   */
  _parseFallbackResponse(text) {
    // 简单的备用解析逻辑
    const lines = text.split('\n').filter(line => line.trim() !== '')
    const replies = []

    for (let i = 0; i < Math.min(3, lines.length); i++) {
      replies.push({
        content: lines[i].replace(/^\d+\.\s*/, '').trim(),
        toneStyle: '通用',
        eqScore: 7
      })
    }

    return replies
  }

  /**
   * 带重试的 API 调用
   * @param {Array} messages - Chat 格式的消息数组
   * @param {string} scenarioId - 场景ID
   * @param {number} retryCount - 当前重试次数
   */
  async _callWithRetry(messages, scenarioId, retryCount = 0) {
    try {
      return await this._callChatAPI(messages, scenarioId)
    } catch (error) {
      if (retryCount < API_CONFIG.MAX_RETRIES) {
        // 等待后重试
        await new Promise(resolve => setTimeout(resolve, API_CONFIG.RETRY_DELAY * (retryCount + 1)))
        return this._callWithRetry(messages, scenarioId, retryCount + 1)
      } else {
        throw error
      }
    }
  }
}

// 导出单例
const geminiService = new GeminiService()

module.exports = geminiService
